<?php

namespace App\Trip\Orders\ApplyRefund;

use App\Models\Plane\PlaneOrderPassengers\PlaneOrderPassenger;
use App\Models\Plane\PlaneOrders\PlaneOrder;
use App\Models\Plane\Rules\PlaneRefundRule;
use App\Trip\Orders\Traits\ThrowErrorMessageTrait;
use App\Trip\Orders\TripOrderState;
use Exception;

class PlaneOrderApplyRefund implements OrderRefund
{
    use ThrowErrorMessageTrait;

    private PlaneOrderPassenger $passenger;
    private PlaneOrder          $order_info;
    private bool                $ignore_worktime_error = false;
    private bool                $has_other_error       = false;

    public function __construct(PlaneOrder $order_info, PlaneOrderPassenger $passenger)
    {
        $this->passenger  = $passenger;
        $this->order_info = $order_info;
    }

    public function canApplyRefundToShow(): bool
    {
        $res = $this->canApplyRefund();
        return $res;
    }

    /**
     * 是否能申请退票退款
     *
     * @return bool
     */
    public function canApplyRefund(): bool
    {
        try {
            $this->validOrderState();
            $this->validOrder();
            $this->validPassengers();
            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * @throws Exception
     */
    private function validOrderState(): void
    {
        if ($this->order_info->isCancel()) {
            $this->throwErrorMessage("订单已取消");
        }
        if (!in_array($this->order_info->getOrderState(), [
            TripOrderState::ORDER_STATE_TICKETED,
            TripOrderState::ORDER_STATE_CHANGED,
            TripOrderState::ORDER_STATE_REFUNDED_PART,
            TripOrderState::ORDER_STATE_REFUNDED,
        ])) {
            $this->throwErrorMessage("当前订单状态不可退票");
        }
        $this->validateOrderFlight();
    }

    /**
     * 验证发车
     *
     * @param $order_train_info
     *
     * @return void
     * @throws Exception
     */
    private function validateOrderFlight(): void
    {
        $plane_info = $this->order_info->getFlightInfo();
        if ($plane_info->isDeparted()) {
            $this->throwErrorMessage("航班已发车");
        }
    }

    /**
     * @throws Exception
     */
    private function validOrder(): void
    {
        if ($this->order_info->isChangeOrigin() && $this->passenger->getOrderState() == TripOrderState::ORDER_STATE_CHANGED) {
            $this->throwErrorMessage("原单已改签成功,不可退票");
        }
    }

    /**
     * @throws Exception
     */
    private function validPassengers()
    {


        if (!$this->has_ticket()) {
            $this->throwErrorMessage('乘客未出票,不支持此退款');
        }

        $flight          = $this->order_info->flight_info;
        $order_passenger = $this->passenger;
        $refundRule      = new PlaneRefundRule();
        if ($order_passenger->cabin) {
            $rule = $refundRule->findOneByCabin($flight->getFlightNo(), $order_passenger->cabin);
            if ($rule?->isNotAllow()) {
                $this->throwErrorMessage("航班舱位{$order_passenger->cabin},不允许退款");
            }

            if ($order_passenger->order_state == TripOrderState::ORDER_STATE_REFUNDING) {
                $this->throwErrorMessage("乘客退款中");
            }

            if ($order_passenger->order_state == TripOrderState::ORDER_STATE_REFUNDED) {
                $this->throwErrorMessage("乘客已退款");
            }


            if ($rule?->isNotEnsure()) {
                $this->setErrorMsg("航班舱位{$order_passenger->cabin},需依据产品规则执行");
            }
        }
    }

    public function has_ticket(): bool
    {
        return $this->passenger->getTicketNumber() != '';
    }

}